iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0

Flutter animation 原生的StatefullWidget
添加 SingleTickerProviderStateMixin,
使用GetX的話 我個人是把animateionController寫在GetXController,
GetX有提供SingleGetTickerProviderMixin.

下面直接看code
GetxController部分
animationController 設定整個動畫在0.5秒.
接下來 設定了兩個animation

  1. flipAnimation:
    Tween 0.0 -> 2.0 用在圖片旋轉.
  2. scaleAnimation:
    這邊用的是TweenSequence 可以設定時間的佔比(weight)和變化量.
    想做一個sacel的 小->大->小 變化的過程(1 -> 2 > 3 -> 2 -> 1)
class ExtensionPageController extends GetxController
    with SingleGetTickerProviderMixin {
      
  late AnimationController animationController;
  late Animation<double> scaleAnimation;
  late Animation<double> flipAnimation;

  @override
  void onInit() {
    animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));

    //小->大->小 變化的過程 (1 -> 2 > 3 -> 2 -> 1)
    scaleAnimation = TweenSequence(<TweenSequenceItem<double>>[
      TweenSequenceItem(tween: Tween(begin: 1.0, end: 2.0), weight: 25),
      TweenSequenceItem(tween: Tween(begin: 2.0, end: 3.0), weight: 25),
      TweenSequenceItem(tween: Tween(begin: 3.0, end: 2.0), weight: 25),
      TweenSequenceItem(tween: Tween(begin: 2.0, end: 1.0), weight: 25),
    ]).animate(animationController);

    flipAnimation = Tween(begin: 0.0, end: 2.0).animate(animationController);
    super.onInit();
  }

  animationStart() {
    animationController.forward(from: 0.0);
  }

}

Widget部分
這邊借用前篇多國語系切換下面還有的空間.

使用GetBuilder和AnimatedBuilder,
IconButton按下觸發動畫 呼叫controller的 animationStart()
AnimatedBuilder 回傳 Transform,
scale 大小(帶入上面寫好的scaleAnimation),
rotateY水平翻轉(flipAnimation),

Expanded(
flex: 4,
child: GetBuilder<ExtensionPageController>(
  init: controller,
  initState: (_) {},
  tag: "imageFlip",
  builder: (_) {
    return AnimatedBuilder(
      animation: controller.animationController,
      builder: (context, child) {
          return Transform(
            child: child,
            alignment: Alignment.center,
            transform: Matrix4.identity()
              ..scale(controller.scaleAnimation.value,
                  controller.scaleAnimation.value, 1)
              ..rotateY(pi * controller.flipAnimation.value),
          );
      },
      child: IconButton(
        icon: Icon(Icons.ac_unit, size: 50),
        onPressed: () => controller.animationStart(),
      ),
    );
  },
),
),

實際效果
https://cdn-images-1.medium.com/max/800/1*hvBSrLziUF5mqwFFoJiVKw.gif

本篇的GitHub source code

下一篇將為大家介紹flutter Dio


上一篇
[Day20] Flutter GetX routing
下一篇
[Day22] Flutter GetX with Dio (一)
系列文
Flutter with GetX, loading*175%歷程 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言